from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


# ------------------------------
# 1. 描述符类：封装元素定位、等待、赋值逻辑
# ------------------------------
class SeleniumElementDescriptor:
    def __init__(self, locator, wait_time=10, wait_condition=EC.element_to_be_clickable):
        self.locator = locator  # 元素定位器（�?(By.ID, "username")�?
        self.wait_time = wait_time  # 显式等待时间
        self.wait_condition = wait_condition  # 等待条件

    def __get__(self, instance, owner_type=None):
        """获取元素：通过实例的driver定位元素"""
        # 类访问时返回描述符自身（�? LoginPage.username_input �? 描述符实例）
        if instance is None:
            return self
        # 实例访问时：用driver执行等待+定位，返回WebElement
        print(f"这是instance：{instance}")
        print(f"这是instance注入的driver：{instance.driver}")
        wait = WebDriverWait(instance.driver, self.wait_time)
        return wait.until(self.wait_condition(self.locator))

    def __set__(self, instance, value):
        """设置元素值：如输入框填值和清空"""
        element = self.__get__(instance)  # 先获取实例元素
        element.clear()
        element.send_keys(value)


# ------------------------------
# 2. 元类：自动将locators字典转为描述符属�?
# ------------------------------
class PageMeta(type):
    _page_registry = {}  # 可选：注册所有页面类，便于管�?

    def __new__(cls, name, bases, namespace):
        # 1. 调用父类创建页面类（如LoginPage�?
        new_page_class = super().__new__(cls, name, bases, namespace)
        # 2. 注册页面类（可选功能）
        cls._page_registry[name] = new_page_class
        # 3. 提取locators字典，动态生成描述符属�?
        locators = namespace.get("locators", {})  # 子类定义的定位器配置
        for elem_name, locator in locators.items():
            # 给页面类添加属性：属性名=elem_name，�?=描述符实�?
            setattr(new_page_class, elem_name, SeleniumElementDescriptor(locator))
        return new_page_class


# ------------------------------
# 3. POM基类：所有页面类的父类，接收driver
# ------------------------------
class BasePage(metaclass=PageMeta):
    print(f"已运行BASEPAGE")

    def __init__(self, driver):
        self.driver = driver  # 接收conftest注入的driver

    def get_title(self):
        """通用方法：获取页面标�?"""
        return self.driver.title

    def go_to_url(self, url):
        """通用方法：跳转页�?"""
        print(f"driver已传入BasePage基类")
        self.driver.get(url)
